package com.ehotting.edsta.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.ehotting.eaf.core.StringHelper;
import com.ehotting.eaf.core.domain.R;
import com.ehotting.eaf.core.utils.StringUtils;
import com.ehotting.eaf.spring.cloud.service.NacosConfigService;
import com.ehotting.edsta.mqbd.api.enums.SysModuleEnum;
import com.ehotting.edsta.system.domain.dto.NodeDto;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 后台首页统计controller
 */
@Api(tags = "NodeController", description = "多节点配置controller")
@RestController
@RequestMapping("/node")
public class NodeController {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final String PRE_NAME = "mqbd-solverInfo";

    @Autowired
    private NacosConfigService nacosConfigService;

    private static String MQDB_NODE = "mqbd";
    private static String SOLVER_NODE = "solver";


    @ApiOperation("获取多节点配置信息")
    @GetMapping("/getConfig")
    public R<Object> getConfig() {
        String content = nacosConfigService.get(PRE_NAME);
        return R.ok(content);
    }

    @ApiOperation("保存多节点配置信息")
    @PostMapping("/saveConfig")
    public R<Object> saveConfig(@RequestBody String data) {
        JSONObject jsonObject = JSONObject.parseObject(data);
        String value = jsonObject.getString("value");

        if (StringHelper.isBlank(value)) {
            return R.fail("输入的配置数据为空");
        }

        // 去除双引号
        value = value.replace("\"","").replace("'","");
        ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
        Map<String, Object> objectMap;
        // 校验格式是否正确
        try {
            objectMap = objectMapper.readValue(value, HashMap.class);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("数据格式有误，请检查后再保存");
        }

        nacosConfigService.save(PRE_NAME, value);

        return R.ok();
    }

    @ApiOperation("导入多节点配置信息")
    @PostMapping("/importExcel")
    public Object importExcel(@RequestParam MultipartFile file, int type) throws IOException {
        // type 0:追加导入，1：覆盖导入

        logger.info("fileName:" + file.getOriginalFilename());

        // 解析表格数据
        LinkedHashMap<String, List<LinkedHashMap<String, Object>>> moduleMap = analysisExcel(file);

        // 组装yml格式
        LinkedHashMap<String, Object> solverMap = new LinkedHashMap<>();
        if (moduleMap.keySet().size() == 0){
            solverMap.put(SOLVER_NODE, "");
        }else {
            solverMap.put(SOLVER_NODE, moduleMap);
        }
        LinkedHashMap<String, Object> mqbdMap = new LinkedHashMap<>();
        mqbdMap.put(MQDB_NODE, solverMap);

        // 保存的yml字符串
        String yamlString = "";

        ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

        try {
            if (type == 1) {
                // 1：覆盖导入
                yamlString = objectMapper.writeValueAsString(mqbdMap);
            } else {
                // 0:追加导入
                String content = nacosConfigService.get(PRE_NAME);
                Map<String, Object> contentMap = objectMapper.readValue(content, HashMap.class);
                Map<String, Object> importServerMap = (Map<String, Object>) contentMap.get(MQDB_NODE);

                if (importServerMap == null){
                    importServerMap = new HashMap<>();
                    contentMap.put(MQDB_NODE, importServerMap);
                }

                Map<String, Object> importModuleMap = (Map<String, Object>) importServerMap.get(SOLVER_NODE);

                if (importModuleMap == null){
                    importModuleMap = new HashMap<>();
                    importServerMap.put(SOLVER_NODE, importModuleMap);
                }

                // 替换模块配置信息
                importModuleMap.putAll(moduleMap);

                yamlString = objectMapper.writeValueAsString(contentMap);
            }

        } catch (Exception e) {
            logger.error("yml字符串转换异常", e);
            return R.fail("yml字符串转换异常：" + e.getMessage());
        }

        yamlString = yamlString.replace("\"","").replace("'","").replace("---", "");

        nacosConfigService.save(PRE_NAME, yamlString);

        return R.ok(yamlString);
    }

    private LinkedHashMap<String, List<LinkedHashMap<String, Object>>> analysisExcel(MultipartFile file) throws IOException {
        LinkedHashMap<String, List<LinkedHashMap<String, Object>>> objectMap = new LinkedHashMap<>();

        InputStream fis = null;
        Workbook workbook = null;

        fis = file.getInputStream();
        int startIndex = file.getOriginalFilename().lastIndexOf(".");
        String postFix = file.getOriginalFilename().substring(startIndex + 1);
        if (postFix.equals("xls")) {
            workbook = new HSSFWorkbook(fis);
        } else {
            workbook = new XSSFWorkbook(fis);
        }

        /**
         * 获取第一个sheet
         */
        Sheet sheet = workbook.getSheetAt(0);

        List<NodeDto> lists = new ArrayList<>();

        /**
         * 从第二行开始读取
         */
        for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {

            /**
             * 获取一行数据
             */
            Row row = sheet.getRow(rowIndex);

            /**
             * 如果这行数据为空则跳过
             */
            if (row == null){
                continue;
            }

            NodeDto nodeDto = new NodeDto();

            for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
                Cell cell = row.getCell(cellIndex);

                if (cell == null){
                    continue;
                }

                switch (cellIndex){
                    case 0: // 名称
                        cell.setCellType(CellType.STRING);
                        nodeDto.setName(cell.getStringCellValue().replace(" ",""));

                        SysModuleEnum sysModuleEnum = SysModuleEnum.getByName(nodeDto.getName());
                        if (sysModuleEnum != null){
                            nodeDto.setModule(sysModuleEnum.getCode());
                        }

                        break;
                    case 1: // ip
                        cell.setCellType(CellType.STRING);
                        nodeDto.setIp(cell.getStringCellValue().replace(" ",""));
                        break;
                    case 2:  // 端口
                        cell.setCellType(CellType.NUMERIC);
                        nodeDto.setPort((int) cell.getNumericCellValue());
                        break;
                }
            }

            lists.add(nodeDto);
        }

        for (NodeDto nodeDto : lists){
            String module = nodeDto.getModule();
            String name = nodeDto.getName();
            String ip = nodeDto.getIp();
            int port = nodeDto.getPort();

            if (StringUtils.isEmpty(module)){
                continue;
            }

            LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
            linkedHashMap.put("ip", ip);
            linkedHashMap.put("port", port);
            linkedHashMap.put("name", name);

            // 取出模块的list
            List<LinkedHashMap<String, Object>> linkedHashMaps = objectMap.get(module);
            if (linkedHashMaps == null){
                linkedHashMaps = new ArrayList<>();
                objectMap.put(module, linkedHashMaps);
            }
            linkedHashMaps.add(linkedHashMap);
        }

        return objectMap;
    }
}
